package com.centerm.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

public class DateUtil {
	
	public static String getDateStringByMillis(long milllis){
		Calendar cal = Calendar.getInstance(); 
		cal.setTimeInMillis(milllis);
		return dateToString(cal.getTime());
	}
	
	/**
	 * 将Date转化为字符串，Date格式为yyyy-MM-dd HH:mm:ss
	 * @param date 格式为"yyyy-MM-dd HH:mm:ss"的时间
	 * @return 格式为"yyyy-MM-dd HH:mm:ss"的String
	 * */
	public static String timeToString(Date date){
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
	}
	
	public static String timeToFileName(Date date){
		return new SimpleDateFormat("yyyyMMddHHmmss").format(date);
	}
	/**
	 * 将Date转化为字符串，Date格式为yyyy-MM-dd
	 * @param date 格式为"yyyy-MM-dd"的时间
	 * @return 格式为"yyyy-MM-dd"的String
	 * */
	public static String dateToString(Date date){
		return new SimpleDateFormat("yyyy-MM-dd").format(date);
	}
	
	/**
	 * 将字符串转化为Date，Date格式为yyyy-MM-dd HH:mm:ss
	 * @param date 时间格式字符串"yyyy-MM-dd HH:mm:ss"
	 * @return 格式为yyyy-MM-dd HH:mm:ss的Date
	 * */
	public static Date stringToTime(String date){
		try {
			return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return new Date();
	}
	
	/**
	 * 将字符串转化为Date，Date格式为yyyy-MM-dd
	 * @param date 时间格式字符串"yyyy-MM-dd"
	 * @return 格式为yyyy-MM-dd的Date
	 * */
	public static Date stringToDate(String date){
		try {
			return new SimpleDateFormat("yyyy-MM-dd").parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return new Date();
	}
	
	/**
	 * @Description    比较两个时间的日期大小
	 * @author lk
	 * @date 2017年8月24日
	 * @param date1
	 * @param date2
	 * @return     相同日期0，左边日期较大>0，右边日期较大<0
	 */
	public static int compareDate(Date leftDate, Date rightDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return Integer.parseInt(sdf.format(leftDate)) - Integer.parseInt(sdf.format(rightDate));
    }
	
	/**
	 * 获取两个日期之间的月份差
	 * @param startDate endDate时间格式字符串"yyyy-MM-dd"
	 * @return Integer 月份差
	 * */
	public static Integer getMonthsBetweenTwoDate(String startDate,String endDate){
		int result = 0;
		int startYear = Integer.parseInt(startDate.substring(0, 4));
		int endYear = Integer.parseInt(endDate.substring(0, 4));
		int startMonth = Integer.parseInt(startDate.substring(5, 7));
		int endMonth = Integer.parseInt(endDate.substring(5, 7)) + 1;
		
		result = (endYear - startYear) * 12 + (endMonth - startMonth);
		return result;
	}
	
	/**
	 * 获取两个日期之间的月份差
	 * @param startDate endDate时间格式字符串"yyyy-MM-dd"
	 * @return Integer 月份差
	 * */
	public static Integer getQuartersBetweenTwoDate(String startDate,String endDate){
		int result = 0;
		int startYear = Integer.parseInt(startDate.substring(0, 4));
		int endYear = Integer.parseInt(endDate.substring(0, 4));
		int startQuarter = Integer.parseInt(startDate.substring(5, 6));
		int endQuarter = Integer.parseInt(endDate.substring(5, 6)) + 1;
		
		result = (endYear - startYear) * 4 + (endQuarter - startQuarter);
		return result;
	}
	
	/**
	 * 获取两个日期之间的年份差
	 * @param startDate endDate时间格式字符串"yyyy-MM-dd"
	 * @return Integer 年份差
	 * */
	public static Integer getYearsBetweenTwoDate(String startDate,String endDate){
		return Integer.parseInt(endDate.substring(0, 4)) - Integer.parseInt(startDate.substring(0, 4)) + 1;
	}
	
	/**
	 * 获取日期的年份
	 * @param date时间格式字符串"yyyy-MM-dd"
	 * @return Integer 年份
	 * */
	public static Integer getYearOfDate(String date){
		return Integer.parseInt(date.substring(0, 4));
	}
	/**
	 * 获取日期的月份
	 * @param date时间格式字符串"yyyy-MM-dd"
	 * @return Integer 月份
	 * */
	public static Integer getMonthOfDate(String date){
		return Integer.parseInt(date.substring(5, 7));
	}
	
	/**
	 * 获取日期的月份
	 * @param date时间格式字符串"yyyy-MM-dd"
	 * @return Integer 月份
	 * */
	public static Integer getDayOfDate(String date){
		return Integer.parseInt(date.substring(8, 10));
	}
	
	/**
	 * 获取日期的月份
	 * @param date时间格式字符串"yyyy-季度"
	 * @return Integer 月份
	 * */
	public static Integer getQuarterOfDate(String date){
		return Integer.parseInt(date.substring(5, 6));
	}
	
	/**
	 * 生成格式字串"yyyy-MM~yyyy-MM(第N季度)"
	 * @param year:Integer 年份
	 * @param quarter:Integer 季度
	 * @return 格式字符串"yyyy-MM~yyyy-MM(第N季度)"
	 * */
	public static String getDateQuarterString(Integer year,Integer quarter){
		Integer startMonth = (quarter - 1) * 3 + 1;
		Integer endMonth = (quarter - 1) * 3 + 3;
		StringBuffer dateString = new StringBuffer();
		dateString.append(String.valueOf(year)).append("-").append(startMonth > 9 ? startMonth : "0" + startMonth)
			.append("~")
			.append(String.valueOf(year)).append("-").append(endMonth > 9 ? endMonth : "0" + endMonth)
			.append("(第").append(quarter).append("季度)");
		
		return dateString.toString();
	}
	
	/**
	 * 生成按季度查询开始日期"yyyy-MM-dd"
	 * @param year:Integer 年份
	 * @param quarter:Integer 季度
	 * @return 日期"yyyy-MM-dd"
	 * */
	public static Date getStartDateQuarter(Integer year,Integer quarter){
		Integer startMonth = (quarter - 1) * 3 + 1;
		StringBuffer dateString = new StringBuffer();
		dateString.append(String.valueOf(year)).append("-").append(startMonth > 9 ? startMonth : "0" + startMonth).append("-01");
		
		return stringToDate(dateString.toString());
	}

	/**
	 * 生成按季度查询结束日期"yyyy-MM-dd"
	 * @param year:Integer 年份
	 * @param quarter:Integer 季度
	 * @return 日期"yyyy-MM-dd"
	 * */
	public static Date getEndDateQuarter(Integer year,Integer quarter){
		Integer endMonth = (quarter - 1) * 3 + 3;
		StringBuffer dateString = new StringBuffer();
		dateString.append(String.valueOf(year)).append("-").append(endMonth > 9 ? endMonth : "0" + endMonth).append("-31");
		
		return stringToDate(dateString.toString());
	}
	
	/**
	 * 生成日期格式字串"yyyy-MM"
	 * @param year:Integer 年份
	 * @param month:Integer 月份
	 * @return date时间格式字符串"yyyy-MM"
	 * */
	public static String getDateMonthString(Integer year,Integer month){
		String dateString = String.valueOf(year);
		if(month > 9){
			dateString = dateString + "-" + month;
		} else {
			dateString = dateString + "-0" + month;
		}
		return dateString;
	}
	
	/**
	 * 生成日期格式字串"yyyy-MM"
	 * @param year:Integer 年
	 * @param month:Integer 月
	 * @param day:Integer 日
	 * @return date时间格式字符串"yyyy-MM-dd"
	 * */
	public static String getDateString(Integer year,Integer month,Integer day){
		String dateString = String.valueOf(year);
		if(month > 9){
			dateString = dateString + "-" + month;
		} else {
			dateString = dateString + "-0" + month;
		}
		if(day > 9){
			dateString = dateString + "-" + day;
		} else {
			dateString = dateString + "-0" + day;
		}
		return dateString;
	}
	
	/**
	 * 判断给定日期是否介于开始时间和结束时间之间
	 * @param date:String 待判断日期
	 * @param startDate:String 开始日期
	 * @param endDate:String 结束日期
	 * @return boolean
	 * */
	public static boolean checkDateBetweenDates(String date,String startDate,String endDate){
		return getYearOfDate(date) >= getYearOfDate(startDate)
				&& getYearOfDate(date) <= getYearOfDate(endDate)
				&& getMonthOfDate(date) >= getMonthOfDate(startDate)
				&& getMonthOfDate(date) <= getMonthOfDate(endDate)
				&& getDayOfDate(date) >= getDayOfDate(startDate)
				&& getDayOfDate(date) <= getDayOfDate(endDate);
	}
	
	/**
	 * 获取月份的最后一天的日期格式为“yyyy-MM-dd”
	 * @param date
	 * @return
	 */
	public static String getMonthLastDay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		  // 不加下面2行，就是取当前时间前一个月的第一天及最后一天
		cal.add(Calendar.MONTH, 1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.add(Calendar.DAY_OF_MONTH, -1);
		Date lastDate = cal.getTime();
		return sdf.format(lastDate);
	}
	
	/**
	 * 创建开始日期和结束日期之间的所有日期的字符串list
	 * @param start
	 * @param end
	 * @return
	 */
	public static List<String> createDateStringBetweenDates(String start, String end) {
		List<String> dateList = new ArrayList<String>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		dateList.add(start);
		while(!start.equals(end)) {
			try {
				Date startDate = sdf.parse(start);
				Calendar cal = Calendar.getInstance();
				cal.setTime(startDate);
				cal.add(Calendar.DAY_OF_MONTH, 1);
				start = sdf.format(cal.getTime());
				dateList.add(start);
			} catch (ParseException e) {
				e.printStackTrace();
				return null;
			}
		}
		return dateList;
	}
	
	public static List<String> createMonthStringBetweenDates(String start, String end) {
		if(start.length() > 7){
			start = start.substring(0, 7);
		}
		if(end.length() > 7){
			end = end.substring(0, 7);
		}
		List<String> dateList = new ArrayList<String>();
		Integer startYear = Integer.parseInt(start.substring(0, 4));
		Integer endYear = Integer.parseInt(end.substring(0, 4));
		Integer startMonth = Integer.parseInt(start.substring(5));
		Integer endMonth = Integer.parseInt(end.substring(5));
		int nums = 13 - startMonth + (endYear - startYear - 1) * 12 + endMonth;
		for(int i=0; i<nums; i++) {
			String monStr = "" + startYear + "-" + (startMonth < 10 ? "0" + startMonth : startMonth);
			dateList.add(monStr);
			if(startMonth >= 12){
				startMonth = 1;
				startYear++;
			} else {
				startMonth++;
			}
		}
		return dateList;
	}

	public static List<String> createYearStringBetweenDates(String start, String end) {
		if(start.length() > 4){
			start = start.substring(0, 4);
		}
		if(end.length() > 4){
			end = end.substring(0, 4);
		}
		List<String> dateList = new ArrayList<String>();
		dateList.add(start);
		while(!start.equals(end)) {
			start = "" + (Integer.parseInt(start) + 1);
			dateList.add(start);
		}
		
		return dateList;
	}
	
	public static List<String> createQuarterStringBetweenDates(String start, String end) {
		List<String> dateList = new ArrayList<String>();
		start = start.substring(0, 7);
		end = end.substring(0, 7);
		int startYear = Integer.parseInt(start.substring(0, 4));
		int endYear = Integer.parseInt(end.substring(0, 4));
		int startQua = dateStrToQuarter(start);
		int endQua = dateStrToQuarter(end);
		int quarterNums = (endYear - startYear - 1) * 4 + 5 - startQua + endQua;
		
		for(int i=0; i<quarterNums; i++) {
			String quaStr = "" + startYear + "年第" + startQua + "季度";
			dateList.add(quaStr);
			if(startQua == 4){
				startQua = 1;
				startYear++;
			} else {
				startQua++;
			}
		}
		return dateList;
	}
	
	public static int dateStrToQuarter(String dateStr) {
		if(dateStr.length() > 7){
			dateStr = dateStr.substring(0, 7);
		}
		int month = Integer.parseInt(dateStr.substring(5));
		return (month - 1) / 3 + 1;
	}
	
	public static int dateToQuarter(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		String dateStr = sdf.format(date);
		int month = Integer.parseInt(dateStr.substring(5));
		return (month - 1) / 3 + 1;
	}
	
	//将传入日期以指定格式转化为字符串
	public static String getFormatDate(Date date,String pattern) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
		return simpleDateFormat.format(date);
	}
	
	public static String getSeasonDateString(String date){
		String title = date.substring(0, 4);	//截取年
		String month = date.substring(5, 7);	//截取月
		String season = "";
		switch ( month )
		{
			case "01":
			{
				season = "1";
				break;
			}
			case "04":
			{
				season = "2";
				break;
			}
			case "07":
			{
				season = "3";
				break;
			}
			case "10":
			{
				season = "4";
				break;
			}
		}
		return title + "年第" + season + "季度";
	}
	
	public static Date dateCalculate(Date date,int year,int month,int day) {
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(date);
		gc.add(1, year);
		gc.add(2, month);
		gc.add(5, day);
		gc.set(gc.get(Calendar.YEAR), gc.get(Calendar.MONTH), gc.get(Calendar.DATE));
		return gc.getTime();
	}
	
    /**
     * 根据Date获取整型日期
     * 
     * @param d
     * @return
     */
    public static Integer getIntDate(Date d) {
        if (d == null)
        {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return getIntDate(c);
    }
    
    /**
     * 根据Calendar获取整型日期
     * 
     * @param c
     * @return
     */
    public static Integer getIntDate(Calendar c) {
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH) + 1;
        int day = c.get(Calendar.DAY_OF_MONTH);
        return year * 10000 + month * 100 + day;
    }

    /**
     * 根据Integer获取Date日期
     * 
     * @param n,形如“20170911”
     * @return
     */
    public static Date getDate(Integer n) {
        if (n == null)
        {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.set(n / 10000, n / 100 % 100 - 1, n % 100,0,0,0);
        return c.getTime();
    }
    
    /**
     * 取得Date型的当前日期,精确到天
     * 
     * @return
     */
    public static Date getToday() {
        return getDate(getIntToday());
    }
    
    /**
     * 取得Integer型的当前日期
     * 
     * @return
     */
    public static Integer getIntToday() {
        return getIntDate(getNow());
    }

    /**
     * 取得Date型的当前时间,精确到秒
     * 
     * @return
     */
    public static Date getNow() {
        return new Date();
    }
    
    /**
     * 计算两个整型日期之间的天数
     * 
     * @param startDate
     * @param endDate
     * @return
     */
    public static Integer daysBetweenDate(Integer startDate, Integer endDate) {
        if (startDate == null || endDate == null)
        {
            return null;
        }
        Calendar c1 = newCalendar(startDate);
        Calendar c2 = newCalendar(endDate);

        Long lg = (c2.getTimeInMillis() - c1.getTimeInMillis()) / 1000 / 60 / 60 / 24;
        return lg.intValue();
    }

    /**
     * 计算两个整型日期之间的天数
     * 
     * @param startDate
     * @param endDate
     * @return
     */
    public static Integer daysBetweenDate(Date startDate, Date endDate) {
        if (startDate == null || endDate == null)
        {
            return null;
        }
        Long interval = endDate.getTime() - startDate.getTime();
        interval = interval / (24 * 60 * 60 * 1000);
        return interval.intValue();
    }
    
    /**
     * 根据年月日生成Calendar
     * 
     * @param year
     * @param month
     * @param day
     * @return
     */
    public static Calendar newCalendar(int year, int month, int day) {
        Calendar ret = Calendar.getInstance();
        if (year < 100)
        {
            year = 2000 + year;
        }
        ret.set(year, month - 1, day);
        return ret;
    }

    /**
     * 根据整型日期生成Calendar
     * 
     * @param date
     * @return
     */
    public static Calendar newCalendar(int date) {
        int year = date / 10000;
        int month = (date % 10000) / 100;
        int day = date % 100;

        Calendar ret = Calendar.getInstance();
        ret.set(year, month - 1, day);
        return ret;
    }
}
